package com.test.dboperations;

import java.util.LinkedList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.google.android.gms.maps.model.LatLng;
import com.test.followme.Globals;
import com.test.user.OtherUser;

public class DBOperation
{
	private static volatile DBOperation instance = null;
	
	private static final String TABLE_FM_NOTIFICATION = "FM_NOTIFICATION";
	private static final String KEY_NTF_PANE = "notification_pane";
	
	private static final String TABLE_FM_FOLLOW = "FM_FOLLOW";
	private static final String KEY_USER_ID = "user_id";
	private static final String KEY_USER_NAME = "user_name";
	private static final String KEY_EMAIL = "email";
	private static final String KEY_ONL_STAT = "onl_stat";
	private static final String KEY_LAT = "lat";
	private static final String KEY_LNG = "lng";
	private static final String KEY_TYPE = "type";
	private static final String[] COLUMNS_FM_FOLLOW =
	{ KEY_USER_ID, KEY_USER_NAME, KEY_EMAIL, KEY_ONL_STAT, KEY_LAT, KEY_LNG, KEY_TYPE };
	
	private DBCore dbCore;
	private SQLiteDatabase db;
	
	private DBOperation(Context context)
	{
		dbCore = new DBCore(context);
		db = dbCore.getWritableDatabase();
	}
	
	public static DBOperation getInstance(Context context)
	{
		if (instance == null)
		{
			synchronized (DBOperation.class)
			{
				// Double check
				if (instance == null)
				{
					instance = new DBOperation(context);
				}
			}
		}
		return instance;
	}
		
	public void openDb()
	{
		if (!db.isOpen())
		{
			db = dbCore.getWritableDatabase();
		}
	}
	
	public void closeDb()
	{
		if (db.isOpen())
		{
			db.close();
		}
	}
	
	private void addNotification(String str)
	{
		Log.i("addNotification : ", str);
		
		ContentValues values = new ContentValues();
		values.put(KEY_NTF_PANE, str);
		
		db.insert(TABLE_FM_NOTIFICATION, null, values);
	}
	
	public List<String> getAllNotifications()
	{
		List<String> notifs = new LinkedList<String>();
		
		String query = "SELECT  * FROM " + TABLE_FM_NOTIFICATION;
		
		Cursor cursor = db.rawQuery(query, null);
		
		String str = "";
		if (cursor.moveToFirst())
		{
			do
			{
				str = cursor.getString(0);
				notifs.add(str);
			}
			while (cursor.moveToNext());
		}
		
		Log.i("getAllNotifications()", notifs.toString());
		
		return notifs;
	}
	
	public int getCountNotification()
	{
		Cursor cursor = db.rawQuery("SELECT  COUNT(*) FROM " + TABLE_FM_NOTIFICATION, null);
		int count = 0;
		if (cursor != null && cursor.getCount() > 0)
		{
			cursor.moveToFirst();
			count = cursor.getInt(0);
		}
		cursor.close();
		
		return count;
	}
	
	private void addUserTables(OtherUser otherUser, int tblType)
	{
		Log.i("addUserTables : ", otherUser.toString() + " :: type : " + tblType);
		
		ContentValues values = new ContentValues();
		values.put(KEY_USER_ID, otherUser.getId());
		values.put(KEY_USER_NAME, otherUser.getName());
		values.put(KEY_EMAIL, otherUser.getMail());
		values.put(KEY_TYPE, tblType);
		
		if (tblType == Globals.TYPE_WHO_I_FOLLOW)
		{
			values.put(KEY_ONL_STAT, otherUser.getOnlStat());
			values.put(KEY_LAT, otherUser.getLocation().latitude);
			values.put(KEY_LNG, otherUser.getLocation().longitude);
		}
		
		db.insert(TABLE_FM_FOLLOW, null, values);
	}
	
	public OtherUser getUser(String userId, int type)
	{
		SQLiteDatabase db = dbCore.getReadableDatabase();
		
		Cursor cursor = db.query(TABLE_FM_FOLLOW, COLUMNS_FM_FOLLOW, " user_id = ?, type = ?", new String[]
		{ userId, String.valueOf(type) }, null, null, null, null);
		
		if (cursor != null)
		{
			cursor.moveToFirst();
		}
		
		OtherUser otherUser = new OtherUser();
		otherUser.setId(cursor.getString(0));
		otherUser.setName(cursor.getString(1));
		otherUser.setMail(cursor.getString(2));
		otherUser.setOnline(Integer.parseInt(cursor.getString(3)));
		otherUser.setLocation(new LatLng(Double.parseDouble(cursor.getString(4)), Double.parseDouble(cursor.getString(5))));
		cursor.close();
		
		Log.i("getUser(" + userId + ")", otherUser.toString());
		
		return otherUser;
	}
	
	public List<OtherUser> getAllUsers(int type)
	{
		List<OtherUser> users = new LinkedList<OtherUser>();
		
		String query = "SELECT  * FROM " + TABLE_FM_FOLLOW;
		
		Cursor cursor = db.rawQuery(query, null);
		
		OtherUser otherUser = null;
		if (cursor.moveToFirst())
		{
			do
			{
				otherUser = new OtherUser();
				
				otherUser.setId(cursor.getString(0));
				otherUser.setName(cursor.getString(1));
				otherUser.setMail(cursor.getString(2));
				
				if (type == Globals.TYPE_WHO_I_FOLLOW)
				{
					otherUser.setOnline(Integer.parseInt(cursor.getString(3)));
					otherUser.setLocation(new LatLng(Double.parseDouble(cursor.getString(4)), Double.parseDouble(cursor.getString(5))));
				}
				
				users.add(otherUser);
			}
			while (cursor.moveToNext());
		}
		cursor.close();
		
		Log.i("getAllUsers : ", users.toString());
		
		return users;
	}
	
	public int getCountRequest()
	{
		Cursor cursor = db.rawQuery("SELECT  COUNT(*) FROM " + TABLE_FM_NOTIFICATION + " WHERE " + KEY_TYPE + "=?", new String[]
		{ String.valueOf(Globals.TYPE_FOLLOW_REQUEST) });
		int count = 0;
		if (cursor != null && cursor.getCount() > 0)
		{
			cursor.moveToFirst();
			count = cursor.getInt(0);
		}
		cursor.close();
		
		return count;
	}
	
	private boolean updateLocation(OtherUser otherUser)
	{
		ContentValues values = new ContentValues();
		
		values.put(KEY_LAT, otherUser.getLocation().latitude);
		values.put(KEY_LNG, otherUser.getLocation().longitude);
		
		int i = db.update(TABLE_FM_FOLLOW, values, KEY_USER_ID + " = ? " + KEY_TYPE + " = ? ", new String[]
		{ otherUser.getId(), String.valueOf(Globals.TYPE_WHO_I_FOLLOW) });
		return i == 1;
	}
	
	private boolean updateOnlStat(OtherUser otherUser)
	{
		ContentValues values = new ContentValues();
		
		values.put(KEY_ONL_STAT, otherUser.getOnlStat());
		
		int i = db.update(TABLE_FM_FOLLOW, values, KEY_USER_ID + " = ? " + KEY_TYPE + " = ? ", new String[]
		{ otherUser.getId(), String.valueOf(Globals.TYPE_WHO_I_FOLLOW) });
		
		return i == 1;
	}
	
	private boolean deleteWhoIFlwUser(OtherUser otherUser)
	{
		int i = db.delete(TABLE_FM_FOLLOW, KEY_USER_ID + " = ? " + KEY_TYPE + " = ? ", new String[]
		{ otherUser.getId(), String.valueOf(Globals.TYPE_WHO_I_FOLLOW) });
		return i == 1;
	}
	
	private void deleteAll()
	{
		db.delete(TABLE_FM_NOTIFICATION, null, null);
		db.delete(TABLE_FM_FOLLOW, null, null);
	}
	
	public synchronized boolean syncDbProcess(OtherUser otherUser, String str,
			int prcType, int tblType)
	{
		boolean retVal = true;
		try
		{
			Log.i("DBOperation", "handleDelete");
			
			db.beginTransaction();
			
			switch (prcType)
			{
				case Globals.deleteAll:
					deleteAll();
					break;
				case Globals.deleteWhoIFlwUser:
					retVal = deleteWhoIFlwUser(otherUser);
					break;
				case Globals.updateLocation:
					retVal = updateLocation(otherUser);
					break;
				case Globals.updateOnlStat:
					retVal = updateOnlStat(otherUser);
				case Globals.addNotification:
					addNotification(str);
				case Globals.addUserTables:
					addUserTables(otherUser, tblType);
				default:
					break;
			}
			
			db.setTransactionSuccessful();
		}
		catch (Exception e)
		{
			retVal = false;
		}
		finally
		{
			db.endTransaction();
		}
		
		return retVal;
	}
}
